package com.video.main_video.common.response;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.core.MethodParameter;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;

public class ZouResponseBodyHandleReturnValue implements HandlerMethodReturnValueHandler, AsyncHandlerMethodReturnValueHandler {

    @Override
    public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
        return supportsReturnType(returnType);
    }

    // 如果被 ZouResponseBody.class 注解修饰则处理
    @Override
    public boolean supportsReturnType(MethodParameter returnType)  {
        return returnType.getParameterType() != ZouBaseResponse.class
                && !ObjectUtils.isEmpty(returnType.getAnnotatedElement().getAnnotation(ZouResponseBody.class));

    }

    // 返回值封装
    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        mavContainer.setRequestHandled(true);
        Class<?> model = returnValue.getClass();
        int code=200;
        String msg="succeed";
        for (Field field : model.getDeclaredFields()) {
            String name = field.getName();
            try{
                if (name.equals("code")){
                    field.setAccessible(true);
                    code=Integer.parseInt(field.get(returnValue).toString());
                }else if(name.equals("error")){
                    field.setAccessible(true);
                    msg=field.get(returnValue).toString();
                }
            }catch (Exception e){
                code=1009;
                msg=e.getMessage();
                break;
            }
        }

        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        assert response != null;
        ZouResponseBody responseBody = returnType.getAnnotatedElement().getAnnotation(ZouResponseBody.class);
        response.setContentType("application/json;charset=utf-8");
        ZouBaseResponse baseResponse = new ZouBaseResponse();
        baseResponse.setCode(code);
        baseResponse.setMsg(msg);
        if(code==200){
            baseResponse.setData(returnValue);
        }
        SerializerFeature[] defaultSerializerFeature = {
                SerializerFeature.DisableCircularReferenceDetect
        };
        /**
         * 替换注解中的序列化格式
         */
        if (!ObjectUtils.isEmpty(responseBody) && !ObjectUtils.isEmpty(responseBody.serializerFeature())) {
            defaultSerializerFeature = responseBody.serializerFeature();
        }
        response.getWriter().write(JSON.toJSONString(baseResponse, defaultSerializerFeature));

    }
}
